home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / Mod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  27.1 KB  |  999 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "RDriver.h"
  25. #include "MOD.h"
  26. #include "FileUtils.h"
  27.  
  28. #ifdef _MAC_H
  29. #if defined(powerc) || defined(__powerc)
  30. enum {
  31.         PlayerPROPlug = kCStackBased
  32.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  33.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  34.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  35.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  36.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  37.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  38. };
  39.  
  40. ProcInfoType __procinfo = PlayerPROPlug;
  41. #else
  42. #include <A4Stuff.h>
  43. #endif
  44. #endif
  45.  
  46. //debugger(Ptr);
  47.  
  48. short FoundNote( short Period)
  49. {
  50. short             note;
  51. short                MODTuning[ 70] =
  52. {
  53.  
  54. // -> Tuning 0
  55.  
  56.     1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
  57.     856,808,762,720,678,640,604,570,538,508,480,453,
  58.     428,404,381,360,339,320,302,285,269,254,240,226,
  59.     214,202,190,180,170,160,151,143,135,127,120,113,
  60.     107,101,95,90,85,80,75,71,67,63,60,56
  61. };
  62.     note = 0xFF;
  63.     
  64.     
  65.     if(Period != 0)
  66.     {
  67.         for(note = 0;note < 60;note++)
  68.         {
  69.             if(Period >= MODTuning[ note]) break;
  70.         }
  71.         if(note >= NUMBER_NOTES) note = 0xFF;
  72.     }
  73.     
  74.     if( note != 0xFF) note += 24;
  75.     
  76.     return note;
  77. }
  78.  
  79. void Convert16to8( Ptr srcPtr, Ptr destPtr, long size)
  80. {
  81. long     i;
  82.  
  83. size /= 2;
  84.  
  85.     for( i = 0; i < size; i ++)
  86.     {
  87.         destPtr[ i] = srcPtr[i*2];
  88.     }
  89. }
  90.  
  91. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  92. {
  93.     if( PosX < 0) PosX = 0;
  94.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  95.         
  96.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  97. }
  98.  
  99. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  100. {
  101.     if( init->sysMemory) return NewPtrSys( size);
  102.     else return NewPtr( size);
  103. }
  104.  
  105. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  106. {
  107.     if( init->sysMemory) return NewPtrSysClear( size);
  108.     else return NewPtrClear( size);
  109. }
  110.  
  111. void AnalyseSignatureMOD( long EOFo, long temp, short *maxInstru, long *PatternSize, short *tracksNo, MODDef* aMOD)
  112. {
  113.     long         test, i;
  114.     Boolean        result;
  115.     
  116.     *maxInstru = 31;
  117.     
  118.     MOT32( &temp);
  119.     
  120.     switch( temp)
  121.     {
  122.         case 'FLT4':    *PatternSize = sizeof( struct MODCom) * 64L * 4L;    *tracksNo = 4;    break;
  123.         case 'FLT8':    *PatternSize = sizeof( struct MODCom) * 64L * 4L;    *tracksNo = 4;    break;
  124.         case 'M.K.':    *PatternSize = sizeof( struct MODCom) * 64L * 4L;    *tracksNo = 4;    break;
  125.         case '5CHN':    *PatternSize = sizeof( struct MODCom) * 64L * 5L;    *tracksNo = 5;    break;
  126.         case '6CHN':    *PatternSize = sizeof( struct MODCom) * 64L * 6L;    *tracksNo = 6;    break;
  127.         case '7CHN':    *PatternSize = sizeof( struct MODCom) * 64L * 7L;    *tracksNo = 7;    break;
  128.         case '8CHN':    *PatternSize = sizeof( struct MODCom) * 64L * 8L;    *tracksNo = 8;    break;
  129.         case '9CHN':    *PatternSize = sizeof( struct MODCom) * 64L * 9L;    *tracksNo = 9;    break;
  130.         case '10CH':    *PatternSize = sizeof( struct MODCom) * 64L * 10L;    *tracksNo = 10;    break;
  131.         case '11CH':    *PatternSize = sizeof( struct MODCom) * 64L * 11L;    *tracksNo = 11;    break;
  132.         case '12CH':    *PatternSize = sizeof( struct MODCom) * 64L * 12L;    *tracksNo = 12;    break;
  133.         case '13CH':    *PatternSize = sizeof( struct MODCom) * 64L * 13L;    *tracksNo = 13;    break;
  134.         case '14CH':    *PatternSize = sizeof( struct MODCom) * 64L * 14L;    *tracksNo = 14;    break;
  135.         case '15CH':    *PatternSize = sizeof( struct MODCom) * 64L * 15L;    *tracksNo = 15;    break;
  136.         case '16CH':    *PatternSize = sizeof( struct MODCom) * 64L * 16L;    *tracksNo = 16;    break;
  137.         case '17CH':    *PatternSize = sizeof( struct MODCom) * 64L * 17L;    *tracksNo = 17;    break;
  138.         case '18CH':    *PatternSize = sizeof( struct MODCom) * 64L * 18L;    *tracksNo = 18;    break;
  139.         case '19CH':    *PatternSize = sizeof( struct MODCom) * 64L * 19L;    *tracksNo = 19;    break;
  140.         case '20CH':    *PatternSize = sizeof( struct MODCom) * 64L * 20L;    *tracksNo = 20;    break;
  141.         case '21CH':    *PatternSize = sizeof( struct MODCom) * 64L * 21L;    *tracksNo = 21;    break;
  142.         case '22CH':    *PatternSize = sizeof( struct MODCom) * 64L * 22L;    *tracksNo = 22;    break;
  143.         case '23CH':    *PatternSize = sizeof( struct MODCom) * 64L * 23L;    *tracksNo = 23;    break;
  144.         case '24CH':    *PatternSize = sizeof( struct MODCom) * 64L * 24L;    *tracksNo = 24;    break;
  145.         case '25CH':    *PatternSize = sizeof( struct MODCom) * 64L * 25L;    *tracksNo = 25;    break;
  146.         case '26CH':    *PatternSize = sizeof( struct MODCom) * 64L * 26L;    *tracksNo = 26;    break;
  147.         case '27CH':    *PatternSize = sizeof( struct MODCom) * 64L * 27L;    *tracksNo = 27;    break;
  148.         case '28CH':    *PatternSize = sizeof( struct MODCom) * 64L * 28L;    *tracksNo = 28;    break;
  149.         case '29CH':    *PatternSize = sizeof( struct MODCom) * 64L * 29L;    *tracksNo = 29;    break;
  150.         case '30CH':    *PatternSize = sizeof( struct MODCom) * 64L * 30L;    *tracksNo = 30;    break;
  151.         case '31CH':    *PatternSize = sizeof( struct MODCom) * 64L * 31L;    *tracksNo = 31;    break;
  152.         case '32CH':    *PatternSize = sizeof( struct MODCom) * 64L * 32L;    *tracksNo = 32;    break;
  153.         
  154.         default:
  155.             *PatternSize     = sizeof( struct MODCom) * 64L * 4L;            *tracksNo = 4;
  156.             
  157.             result = true;
  158.             test = 0;
  159.             for( i = 0; i < 15; i++)
  160.             {
  161.                 test += aMOD->fid[i].numWords;
  162.                 if( aMOD->fid[i].fineTune > 0x0F) result = false;
  163.                 
  164.                 if( aMOD->fid[i].loopWords > aMOD->fid[i].numWords) result = false;
  165.             }
  166.             
  167.             if( EOFo != -1)
  168.             {
  169.                 long PatMax = 0;
  170.                 for(i=0; i<128; i++)
  171.                 {
  172.                     if( aMOD->oPointers[i] < 0) aMOD->oPointers[i] = 0;
  173.                     if( aMOD->oPointers[i] > 128) aMOD->oPointers[i] = 0;
  174.                     
  175.                     if( aMOD->oPointers[i] >= PatMax)    PatMax = aMOD->oPointers[i];
  176.                 }
  177.                 PatMax++;
  178.                 
  179.                 if( PatMax * *PatternSize + test > EOFo) result = false;
  180.             }
  181.             
  182.             if( test == 0) result = false;
  183.                         
  184.             if( result) *maxInstru         = 15;
  185.             else *maxInstru             = 0;
  186.         break;
  187.     }
  188. }
  189.  
  190. struct MODCom* GetMODCommand( short position, short whichTracks, short whichPattern, short maxTracks, Ptr PatPtr)
  191. {
  192.     struct MODCom*    myMODCom;
  193.     
  194.     myMODCom =    (struct MODCom*) (PatPtr +
  195.                                 whichPattern * 64L * sizeof( struct MODCom) * maxTracks +
  196.                                 position * sizeof( struct MODCom) * maxTracks +
  197.                                 whichTracks * sizeof( struct MODCom));
  198.     
  199.     return myMODCom;
  200. }
  201.  
  202. OSErr PPConvertMod2Mad( Ptr aMOD,long MODSize, MADMusic    *theMAD, MADDriverSettings* init)
  203. {
  204.     short             i, PatMax, x, tracksNo, z, maxInstru;
  205.     long             sndSize, OffSetToSample, MPatSize, temp, inOutCount;
  206.     Ptr                theInstrument[ 64], MaxPtr;
  207.     long             finetune[16] = 
  208.     {
  209.         8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  210.         7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  211.     };
  212.     /**** Variables for MAD File *****/
  213.     Cmd                            *aCmd;
  214.  
  215.     /**** Variables for MOD File *****/
  216.     MODDef                     *theMOD;
  217.     struct MODPat        *PatInt;
  218.     MODDef                    *MODInt;
  219.     struct MODCom        *n;
  220.     /********************************/
  221.     
  222.     theMOD = ((MODDef*) aMOD);
  223.     MaxPtr = (Ptr) theMOD;
  224.     MaxPtr += MODSize;
  225.     
  226.     temp = *((long*)(aMOD + 0x438));        // Signature...
  227.     
  228.     AnalyseSignatureMOD( -1, temp, &maxInstru, &MPatSize, &tracksNo, theMOD);
  229.     
  230.     if( maxInstru == 0)
  231.     {
  232.         return MADFileNotSupportedByThisPlug;    // This file is NOT a Mod file !!!!!! This should NEVER happen !
  233.     }
  234.     else if( maxInstru == 15)                // Old Mods format with 15 instruments
  235.     {
  236.         MODInt = (MODDef*) ( (Ptr) theMOD - (Ptr) 0x1E0);
  237.         PatInt = (struct MODPat*) ((Ptr) MODInt->patterns - (Ptr) 0x4);
  238.         
  239.         PatMax = 0;
  240.         for(i=0; i<128; i++)
  241.         {
  242.             if( MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0;
  243.             if( MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0;
  244.         
  245.             if( MODInt->oPointers[i] >= PatMax)    PatMax = MODInt->oPointers[i];
  246.         }
  247.         PatMax++;
  248.         
  249.     //    if( MODInt->numPointers > 64) MODInt->numPointers = 64;
  250.     //    for(i=64; i<128; i++) MODInt->oPointers[i] = 0;
  251.         
  252.         OffSetToSample = (long) 0x258 + PatMax * MPatSize;
  253.     }
  254.     else                                    // Mods format with 32 instruments
  255.     {
  256.         MODInt    = theMOD;
  257.         PatInt    = MODInt->patterns;
  258.         
  259.         PatMax = 0;
  260.         for(i=0; i<128; i++)
  261.         {
  262.             if( MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0;
  263.             if( MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0;
  264.             
  265.             if( MODInt->oPointers[i] >= PatMax) PatMax = MODInt->oPointers[i];
  266.         }
  267.         PatMax++;
  268.         
  269.         OffSetToSample = (long) 0x43c + PatMax * MPatSize;
  270.     }
  271.     
  272.     for( i = 0; i < maxInstru ; i++)
  273.     {
  274.         theInstrument[ i] = (Ptr) ((long) theMOD + (long) OffSetToSample);
  275.         
  276.         MOT16( &theMOD->fid[ i].numWords);
  277.         MOT16( &theMOD->fid[ i].loopWord);
  278.         MOT16( &theMOD->fid[ i].loopWords);
  279.         
  280.         sndSize = ((long) theMOD->fid[i].numWords) * 2L;
  281.         
  282.         if( theInstrument[i] + sndSize > MaxPtr)
  283.         {
  284.             theMOD->fid[i].numWords = MaxPtr - theInstrument[i];
  285.             theMOD->fid[i].numWords /= 2L;
  286.             
  287.             if( theMOD->fid[i].numWords < 0) theMOD->fid[i].numWords = 0;
  288.                     
  289.             sndSize = ((long) theMOD->fid[i].numWords) * 2L;
  290.         }
  291.         
  292.         OffSetToSample += sndSize;
  293.         
  294.         if( theMOD->fid[i].loopWords > 2 && sndSize > 0)
  295.         {
  296.             if( (long) theMOD->fid[i].loopWord +
  297.                 (long) theMOD->fid[i].loopWords > 
  298.                 (long) theMOD->fid[i].numWords)
  299.             {
  300.                 theMOD->fid[ i].loopWords =    (long) theMOD->fid[i].numWords -
  301.                                             (long) theMOD->fid[i].loopWord;
  302.         
  303.                 if( (long) theMOD->fid[i].loopWord +
  304.                 (long) theMOD->fid[i].loopWords > 
  305.                 (long) theMOD->fid[i].numWords)
  306.                 {
  307.                     theMOD->fid[i].loopWord = 0;
  308.                     theMOD->fid[i].loopWords = 0;
  309.                 }
  310.             }
  311.         }
  312.         else
  313.         {
  314.             theMOD->fid[i].loopWord = 0;
  315.             theMOD->fid[i].loopWords = 0;
  316.         }
  317.     }
  318.     
  319.     /***************************************************************/
  320.     /******** MOD is ready to be converted into MAD File ***********/
  321.     /***************************************************************/
  322.     
  323.     inOutCount = sizeof( MADSpec);
  324.     theMAD->header = (MADSpec*) MADPlugNewPtrClear( inOutCount, init);
  325.     if( theMAD->header == 0L) return MADNeedMemory;
  326.     
  327.     MADstrcpy( theMAD->header->infos, (Ptr) "Converted by PlayerPRO MOD Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  328.     
  329.     theMAD->header->MAD = 'MADI';
  330.     
  331.     for(i=0; i<22; i++) theMAD->header->name[i] = theMOD->NameSignature[i];
  332.     
  333.     theMAD->header->tempo = 125;
  334.     theMAD->header->speed = 6;
  335.     theMAD->header->numPat = PatMax;
  336.     theMAD->header->numPointers = MODInt->numPointers;
  337.     
  338.     for(i=0; i<128; i++) theMAD->header->oPointers[ i] = MODInt->oPointers[ i];
  339.     
  340.     theMAD->header->numChn = tracksNo;
  341.     
  342.     x = 1;
  343.     for( i = 0; i < MAXTRACK; i++)
  344.     {
  345.         if( x > 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  346.         else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  347.         x--;
  348.         
  349.         if( x == -2) x = 2;
  350.         
  351.         theMAD->header->chanVol[ i] = MAX_VOLUME;
  352.     }
  353.     
  354.     theMAD->header->generalVol        = 64;
  355.     theMAD->header->generalSpeed    = 80;
  356.     theMAD->header->generalPitch    = 80;
  357.     
  358.     /////////////////////////////////
  359.     // Instruments &  samples
  360.     /////////////////////////////////
  361.     
  362.     theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  363.     if( !theMAD->fid) return MADNeedMemory;
  364.     
  365.     theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  366.     if( !theMAD->sample) return MADNeedMemory;
  367.     
  368.     for(i = 0; i < maxInstru; i++)
  369.     {
  370.         for( x = 0; x < 22; x++) theMAD->fid[i].name[x] = theMOD->fid[i].Filename[x];
  371.         theMAD->fid[i].type = 0;
  372.         theMAD->fid[i].volFade = DEFAULT_VOLFADE;
  373.         
  374.         if( theMOD->fid[ i].numWords > 0)
  375.         {
  376.             sData    *curData;
  377.             
  378.             theMAD->fid[i].numSamples = 1;
  379.             
  380.             curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  381.             
  382.             curData->size        = theMOD->fid[i].numWords * 2L;
  383.             curData->loopBeg     = theMOD->fid[i].loopWord*2L;
  384.             curData->loopSize     = theMOD->fid[i].loopWords*2L;
  385.             curData->vol        = theMOD->fid[i].volume;
  386.             curData->c2spd        = finetune[ theMOD->fid[i].fineTune&0xf];
  387.             curData->loopType    = 0;
  388.             curData->amp        = 8;
  389.             curData->relNote    = 0;
  390.         //    for( x = 0; x < 22; x++) curData->name[x] = theMOD->fid[ i].Filename[ x];
  391.             
  392.             
  393.             curData->data         = MADPlugNewPtr( curData->size, init);
  394.             if( curData->data == 0L) return MADNeedMemory;
  395.                 
  396.             BlockMove( theInstrument[i], curData->data, curData->size);
  397.             
  398.             if( theInstrument[i] + curData->size> MaxPtr) DebugStr("\pMax Ptr Instru");
  399.         }
  400.         else theMAD->fid[ i].numSamples = 0;
  401.     }
  402.     
  403.     for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  404.     
  405.     for(i=0; i<theMAD->header->numPat; i++)
  406.     {
  407.         theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * 64L * sizeof( Cmd), init);
  408.         if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  409.         
  410.         theMAD->partition[ i]->header.size         = 64L;
  411.         theMAD->partition[ i]->header.compMode     = 'NONE';
  412.         
  413.         for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
  414.         
  415.         theMAD->partition[ i]->header.patBytes = 0L;        theMAD->partition[ i]->header.unused2 = 0L;
  416.                 
  417.         for(x=0; x<64; x++)
  418.         {
  419.             for(z=0; z<theMAD->header->numChn; z++)
  420.             {
  421.                 aCmd = GetMADCommand(  x,  z, theMAD->partition[ i]);
  422.                 
  423.                 /////////////
  424.                 
  425.                 n     =     GetMODCommand(    x,
  426.                                         z,
  427.                                         i,
  428.                                         theMAD->header->numChn,
  429.                                         (Ptr) PatInt);
  430.                 
  431.                 if( (Ptr) n > MaxPtr) DebugStr("\pMax Ptr GetMODCommand");
  432.                 
  433.                 aCmd->ins = (n->a&0x10)|(n->c>>4);
  434.                 aCmd->note = FoundNote( (((unsigned short)n->a&0xf)<<8)+n->b);
  435.                 
  436.                 aCmd->cmd = n->c & 0x0F;
  437.                 
  438.                 if( aCmd->cmd == 0x0C)
  439.                 {
  440.                     aCmd->vol    = 0x10 + (n->d);
  441.                     if( aCmd->arg > 0x50) aCmd->vol = 0x50;
  442.                     aCmd->cmd     = 0;
  443.                     aCmd->arg     = 0;
  444.                 }
  445.                 else
  446.                 {
  447.                     aCmd->arg     = n->d;
  448.                     aCmd->vol    = 0xFF;
  449.                 }
  450.             }
  451.         }
  452.     }
  453.     for( i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[ i] = 0L;
  454.     
  455.     return noErr;
  456. }
  457.  
  458. long ConvertSampleC4SPD( Ptr src, long srcSize, short amp, long srcC4SPD, Ptr dst, long dstC4SPD)
  459. {
  460.     short    *src16 = (short*) src, *dst16 = (short*) dst;
  461.     Ptr        src8 = src, dst8 = dst;
  462.     long    x;
  463.     
  464.     if( dstC4SPD > srcC4SPD) DebugStr("\pWHAT ARE YOU DOING???");
  465.     
  466.     if( amp == 8)
  467.     {
  468.         for( x = 0; x < srcSize; x++)
  469.         {
  470.             dst8[ (x * dstC4SPD) / srcC4SPD] = src8[ x];
  471.         }
  472.     }
  473.     else
  474.     {
  475.         for( x = 0; x < srcSize/2; x++)
  476.         {
  477.             dst16[ (x * dstC4SPD) / srcC4SPD] = src16[ x];
  478.         }
  479.     }
  480.     
  481.     return (srcSize * dstC4SPD) / srcC4SPD;
  482. }
  483.  
  484. Ptr PPConvertMad2Mod( MADMusic *theMAD, MADDriverSettings *init, long *PtrSize)
  485. {
  486.     long                 i, x, z, maxInstru;
  487.     long                 OffSetToSample, InstruSize, *alpha;
  488.     Ptr                    theInstrument[ 64], destPtr;
  489.     Boolean                CheckGoodMod;
  490.     char                redut[4];
  491.     short                MODTuning[ 75] =
  492.                             
  493.                         {
  494.  
  495.                         // -> Tuning 0
  496.                         
  497.                             1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
  498.                             856,808,762,720,678,640,604,570,538,508,480,453,
  499.                             428,404,381,360,339,320,302,285,269,254,240,226,
  500.                             214,202,190,180,170,160,151,143,135,127,120,113,
  501.                             107,101,95,90,85,80,75,71,67,63,60,56
  502.                         };
  503.                             
  504.     /**** Variables for MAD file ****/
  505.     
  506.     Cmd                    *aCmd;
  507.  
  508.     /**** Variables for MOD file ****/
  509.     
  510.     MODDef                 *theMOD;
  511.     Ptr                    maxMOD;
  512.     struct MODCom        *n;
  513.     /********************************/
  514.  
  515.     maxInstru = 31;
  516.     
  517.     InstruSize = 0;
  518.     for( i = 0; i < maxInstru ; i++)
  519.     {
  520.         if( theMAD->fid[ i].numSamples > 0)
  521.         {
  522.             long dstSize;
  523.             
  524.             theInstrument[ i] = theMAD->sample[ i*MAXSAMPLE + 0]->data;
  525.             
  526.             dstSize = theMAD->sample[ i*MAXSAMPLE + 0]->size;
  527.             
  528.             if( theMAD->sample[ i*MAXSAMPLE + 0]->c2spd < 7895) dstSize = ( dstSize * 8363L) / theMAD->sample[ i*MAXSAMPLE + 0]->c2spd;
  529.             
  530.             InstruSize += dstSize;
  531.         }
  532.     }
  533.     
  534.     /******** MAD is ready to be converted **********/
  535.     /******** Copy information in the MOD file    ***/
  536.     
  537.     *PtrSize = 0x43c + InstruSize + theMAD->header->numChn * 64L * theMAD->header->numPat * sizeof( struct MODCom);
  538.     
  539.     theMOD = (MODDef*) MADPlugNewPtr( *PtrSize + 25000L, init);
  540.     if( theMOD == 0L) return 0L;
  541.     
  542.     maxMOD = ((Ptr) theMOD + *PtrSize);
  543.     
  544.     theMOD->longFmtSignature = 'M.K.';
  545.     if( theMAD->header->numChn > 4)
  546.     {
  547.         if( theMAD->header->numChn >= 10)
  548.         {
  549.             redut[0] = 0x30 + (theMAD->header->numChn / 10);
  550.             redut[1] = 0x30 + (theMAD->header->numChn - ((theMAD->header->numChn / 10) * 10));
  551.             redut[2] = 'C';
  552.             redut[3] = 'H';
  553.         }
  554.         else
  555.         {
  556.             redut[0] = 0x30 + theMAD->header->numChn;
  557.             redut[1] = 'C';
  558.             redut[2] = 'H';
  559.             redut[3] = 'N';
  560.         }
  561.         
  562.         alpha = (long*) redut;
  563.         
  564.         theMOD->longFmtSignature = *alpha;
  565.     }
  566.     
  567.     for(i=0; i<20; i++) theMOD->NameSignature[i] = theMAD->header->name[i];
  568.     
  569.     CheckGoodMod = false;
  570.     theMOD->numPointers = theMAD->header->numPointers;
  571.     for(i=0; i<128; i++)
  572.     {
  573.         theMOD->oPointers[ i] = theMAD->header->oPointers[ i];
  574.         if( theMOD->oPointers[ i] == theMAD->header->numPat - 1) CheckGoodMod = true;
  575.     }
  576.     if( !CheckGoodMod) theMOD->oPointers[ theMOD->numPointers + 1] = theMAD->header->numPat - 1;
  577.     
  578.     for(i=0; i<maxInstru; i++)
  579.     {
  580.         if( theMAD->fid[ i].numSamples > 0)
  581.         {
  582.             sData    *curData = theMAD->sample[ i*MAXSAMPLE + 0];
  583.             short    temp;
  584.             
  585.             for( x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = theMAD->fid[i].name[x];
  586.             
  587.             if( curData->size/2L > 0xFFFFUL) theMOD->fid[i].numWords = 0xFFFFUL;
  588.             else theMOD->fid[i].numWords = (short) (curData->size / 2L);
  589.             
  590.             temp = (curData->c2spd - NOFINETUNE) / 50;
  591.             if( temp < 0) temp += 16;
  592.             
  593.             theMOD->fid[i].fineTune        = temp;
  594.             
  595.             theMOD->fid[i].volume         = curData->vol;
  596.             theMOD->fid[i].loopWord     = curData->loopBeg / 2L;
  597.             theMOD->fid[i].loopWords     = curData->loopSize / 2L;
  598.             
  599.             if( curData->c2spd > 8757 || curData->c2spd < 7895)
  600.             {
  601.                 theMOD->fid[i].fineTune = 0;
  602.                 theMOD->fid[i].loopWord = ((curData->loopBeg / 2L) * 8363L) / curData->c2spd;
  603.                 theMOD->fid[i].loopWords = ((curData->loopSize / 2L) * 8363L) / curData->c2spd;
  604.                 theMOD->fid[i].numWords = (theMOD->fid[i].numWords * 8363L) / curData->c2spd;
  605.             }
  606.         }
  607.         else
  608.         {
  609.             for( x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = 0;
  610.             
  611.             theMOD->fid[i].numWords     = 0;
  612.             theMOD->fid[i].fineTune     = 0;
  613.             theMOD->fid[i].volume         = 64;
  614.             theMOD->fid[i].loopWord     = 0;
  615.             theMOD->fid[i].loopWords     = 0;
  616.         }
  617.     }
  618.     
  619.     InstruSize = 0L;
  620.     
  621.     OffSetToSample = (long) 0x43c + theMAD->header->numPat * sizeof( struct MODCom) * 64L * theMAD->header->numChn;
  622.     
  623.     for(i=0; i<maxInstru; i++)
  624.     {
  625.         sData    *curData = theMAD->sample[ i*MAXSAMPLE + 0];
  626.         
  627.         if( theMAD->fid[ i].numSamples > 0)
  628.         {
  629.             destPtr = (Ptr) ((long) theMOD + (long) OffSetToSample + (long) InstruSize);
  630.             
  631.             if( curData->c2spd > 8757 || curData->c2spd < 7895)
  632.             {
  633.                 ConvertSampleC4SPD( theInstrument[ i], curData->size, curData->amp, curData->c2spd, destPtr, 8363);
  634.             }
  635.             else BlockMove( theInstrument[ i], destPtr, (long) (theMOD->fid[i].numWords) * 2L);
  636.             if( destPtr + (theMOD->fid[i].numWords) * 2L > maxMOD) DebugStr("\pOut");
  637.             
  638.             if( theMOD->fid[i].numWords > 0)
  639.             {
  640.                 if( curData->amp == 16)
  641.                 {
  642.                     Convert16to8(    destPtr,
  643.                                     destPtr, 
  644.                                     (long) (theMOD->fid[i].numWords) * 2L);
  645.                     
  646.                     theMOD->fid[i].loopWord /=2;
  647.                     theMOD->fid[i].loopWords /=2;
  648.                     theMOD->fid[i].numWords /= 2;
  649.                 }
  650.                 
  651.                 if( curData->stereo)
  652.                 {
  653.                     for( x = 0 ; x < (theMOD->fid[ i].numWords) * 2L; x+=2)
  654.                     {
  655.                         destPtr[ x / 2] = ((long) destPtr[ x] + (long) destPtr[ x + 1]) / 2L;
  656.                     }
  657.                     
  658.                     theMOD->fid[i].loopWord /=2;
  659.                     theMOD->fid[i].loopWords /=2;
  660.                     theMOD->fid[i].numWords /= 2;
  661.                 }
  662.             }
  663.             
  664.             InstruSize += (long) (theMOD->fid[i].numWords) * 2L;
  665.         }
  666.     }
  667.     
  668.     for(i=0; i<theMAD->header->numPat; i++)
  669.     {
  670.         Cmd            nullCmd;
  671.         
  672.         nullCmd.ins        = 0;
  673.         nullCmd.note    = 0xFF;
  674.         nullCmd.cmd        = 0;
  675.         nullCmd.arg        = 0;
  676.         nullCmd.vol        = 0xFF;
  677.         nullCmd.unused    = 0;
  678.         
  679.         for(x=0; x < 64; x++)
  680.         {
  681.             for(z=0; z < theMAD->header->numChn; z++)
  682.             {
  683.                 short        note;
  684.                 
  685.                 if( x < theMAD->partition[ i]->header.size)
  686.                 {
  687.                     aCmd     = GetMADCommand(     x,
  688.                                                 z,
  689.                                                 theMAD->partition[ i]);
  690.                 }
  691.                 else aCmd = &nullCmd;
  692.                 
  693.                 n             = GetMODCommand(    x,
  694.                                                 z,
  695.                                                 i,
  696.                                                 theMAD->header->numChn,
  697.                                                 (Ptr) theMOD->patterns);
  698.                 
  699.                 if( (Ptr) n > maxMOD) DebugStr("\pOut");
  700.                 if( (Ptr) n < (Ptr) theMOD) DebugStr("\pOut");
  701.                 
  702.                 n->a = aCmd->ins & 0xF0;
  703.                 n->c = (aCmd->ins & 0x0F)<<4;
  704.                 
  705.                 if( aCmd->note != 0xFF && aCmd->note != 0xFE)
  706.                 {
  707.                     short curNote;
  708.                     
  709.                     if( aCmd->ins != 0)
  710.                     {
  711.                         if( theMAD->fid[ aCmd->ins-1].numSamples > 0)
  712.                                 curNote = aCmd->note + theMAD->sample[ (aCmd->ins-1)*MAXSAMPLE + 0]->relNote;
  713.                         else     curNote = aCmd->note;
  714.                     }
  715.                     else curNote = aCmd->note;
  716.                     
  717.                     curNote -= 24;
  718.                     
  719.                     if( curNote > 0 && curNote < 65) curNote = MODTuning[ curNote];
  720.                     else curNote = 0;
  721.                     
  722.                     n->b = curNote & 0xFF;
  723.                     n->a = n->a + (curNote>>8);
  724.                 }
  725.                 else
  726.                 {
  727.                     n->b = 0;
  728.                     n->a = n->a + 0x0;
  729.                 }
  730.                 
  731.                 if( aCmd->vol != 0xFF && aCmd->cmd == 0 && aCmd->arg == 0)
  732.                 {
  733.                     if( aCmd->vol >= 0x10 && aCmd->vol <= 0x50)
  734.                     {
  735.                         n->c = n->c + 0xC;
  736.                         n->d = aCmd->vol - 0x10;
  737.                     }
  738.                 }
  739.                 else
  740.                 {
  741.                     n->c = n->c + (aCmd->cmd & 0x0F);
  742.                     n->d = aCmd->arg;
  743.                 }
  744.             }
  745.         }
  746.     }
  747.     
  748.     // Default speed & tempo
  749.     
  750.     if( theMAD->header->tempo != 125 || theMAD->header->speed != 6)
  751.     {
  752.         n     = GetMODCommand(    0,
  753.                                 theMAD->header->numChn-1,
  754.                                 theMAD->header->oPointers[ 0],
  755.                                 theMAD->header->numChn,
  756.                                 (Ptr) theMOD->patterns);
  757.         
  758.         if( (Ptr) n > maxMOD) DebugStr("\pOut");
  759.         if( (Ptr) n < (Ptr) theMOD) DebugStr("\pOut");
  760.         
  761.         n->a = 0;
  762.         n->b = 0;
  763.         n->c = 0;
  764.         n->c = n->c + 0x0F;            // speed
  765.         n->d = theMAD->header->speed;
  766.         
  767.         n     = GetMODCommand(    0,
  768.                                 theMAD->header->numChn-2,
  769.                                 theMAD->header->oPointers[ 0],
  770.                                 theMAD->header->numChn,
  771.                                 (Ptr) theMOD->patterns);
  772.         
  773.         if( (Ptr) n > maxMOD) DebugStr("\pOut");
  774.         if( (Ptr) n < (Ptr) theMOD) DebugStr("\pOut");
  775.         
  776.         n->a = 0;
  777.         n->b = 0;
  778.         n->c = 0;
  779.         n->c = n->c + 0x0F;            // tempo
  780.         n->d = theMAD->header->tempo;
  781.     }
  782.     
  783.     return( (Ptr) theMOD);
  784. }
  785.  
  786. OSErr ExtractMODInfo( PPInfoRec *info, Ptr AlienFile)
  787. {
  788.     MODDef    *myMOD = ( MODDef*) AlienFile;
  789.     long    PatternSize;
  790.     short    i;
  791.     short    maxInstru;
  792.     
  793.     /*** Signature ***/
  794.     
  795.     info->signature = myMOD->longFmtSignature;
  796.     
  797.     /*** Internal name ***/
  798.     
  799.     myMOD->NameSignature[ 19] = '\0';
  800.     MADstrcpy( info->internalFileName, myMOD->NameSignature);
  801.     
  802.     /*** Check MOD Type ***/
  803.     
  804.     AnalyseSignatureMOD( -1, info->signature, &maxInstru, &PatternSize, &info->totalTracks, myMOD);
  805.     if( maxInstru == 0)
  806.     {
  807.         return MADFileNotSupportedByThisPlug;
  808.     }
  809.     else if( maxInstru == 15)    // Old mod format
  810.     {
  811.         info->signature = '----';
  812.         myMOD = (MODDef*) ((Ptr) myMOD - (Ptr) 0x1E0);
  813.     }
  814.     
  815.     /*** Total Patterns ***/
  816.     
  817.     info->totalPatterns = 0;
  818.     for( i = 0; i < 128; i++)
  819.     {
  820.         if( myMOD->oPointers[ i] >= info->totalPatterns)    info->totalPatterns = myMOD->oPointers[ i];
  821.     }
  822.     info->totalPatterns++;
  823.     
  824.     /*** Partition Length ***/
  825.     
  826.     info->partitionLength = myMOD->numPointers;
  827.     
  828.     /*** Total Instruments ***/
  829.     
  830.     for( i = 0, info->totalInstruments = 0; i < maxInstru ; i++)
  831.     {
  832.         if( myMOD->fid[ i].numWords > 5) info->totalInstruments++;
  833.     }
  834.     
  835.     MADstrcpy( info->formatDescription, "MOD Plug");
  836.     
  837.     return noErr;
  838. }
  839.  
  840. OSErr TestMODFile( Ptr AlienFile, long EOFo)
  841. {
  842.     short        maxInstru;
  843.     long        PatternSize;
  844.     short        tracksNo;
  845.     
  846.     AnalyseSignatureMOD( EOFo, *((long*)(AlienFile + 0x438)), &maxInstru, &PatternSize, &tracksNo, (MODDef*) AlienFile);
  847.     
  848.     if( maxInstru == 0) return MADFileNotSupportedByThisPlug;
  849.     else return noErr;
  850. }
  851.  
  852. #ifndef _MAC_H
  853.  
  854. extern "C" EXP OSErr FillPlug( PlugInfo *p);
  855. extern "C" EXP OSErr mainPLUG( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init);
  856.  
  857. EXP OSErr FillPlug( PlugInfo *p)        // Function USED IN DLL - For PC & BeOS
  858. {
  859.     MADstrcpy( p->type,         ".MOD");        // NEVER MORE THAN 4 CHARS !!!!!!!!
  860.     MADstrcpy( p->MenuName,     "MOD Files");
  861.     p->mode    =    'EXIM';
  862.     
  863.     return noErr;
  864. }
  865. #endif
  866.  
  867. /*****************/
  868. /* MAIN FUNCTION */
  869. /*****************/
  870. #ifdef _MAC_H
  871. OSErr main( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  872. #else
  873. EXP OSErr mainPLUG( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  874. #endif
  875. {
  876.     OSErr        myErr;
  877.     Ptr            AlienFile;
  878.     long        sndSize;
  879.     UNFILE    iFileRefI;
  880.     
  881.     #ifdef _MAC_H
  882.         #ifndef powerc
  883.             long    oldA4 = SetCurrentA4();            //this call is necessary for strings in 68k code resources
  884.         #endif
  885.     #endif
  886.     
  887.     myErr = noErr;
  888.     
  889.     switch( order)
  890.     {
  891.         case 'IMPL':
  892.             iFileRefI = iFileOpen( AlienFileName);
  893.             if( iFileRefI)
  894.             {
  895.                 sndSize = iGetEOF( iFileRefI);
  896.                 
  897.                 // ** MEMORY Test Start
  898.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  899.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  900.                 // ** MEMORY Test End
  901.                 
  902.                 else
  903.                 {
  904.                     DisposePtr( AlienFile);
  905.                     
  906.                     AlienFile = MADPlugNewPtr( sndSize, init);
  907.                     iRead( sndSize, AlienFile, iFileRefI);
  908.                     
  909.                     myErr = TestMODFile( AlienFile, sndSize);
  910.                     if( myErr == noErr)
  911.                     {
  912.                         myErr = PPConvertMod2Mad( AlienFile, sndSize, MadFile, init);
  913.                     }
  914.                     
  915.                     DisposePtr( AlienFile);    AlienFile = 0L;
  916.                 }
  917.                 iClose( iFileRefI);
  918.             }
  919.             else myErr = MADReadingErr;
  920.         break;
  921.         
  922.         case 'TEST':
  923.             iFileRefI = iFileOpen( AlienFileName);
  924.             if( iFileRefI)
  925.             {
  926.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  927.                 
  928.                 AlienFile = MADPlugNewPtr( sndSize, init);
  929.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  930.                 else
  931.                 {
  932.                     iRead( sndSize, AlienFile, iFileRefI);
  933.                     
  934.                     sndSize = iGetEOF( iFileRefI);
  935.                     
  936.                     myErr = TestMODFile( AlienFile, sndSize);
  937.                     
  938.                     DisposePtr( AlienFile);    AlienFile = 0L;
  939.                 }
  940.                 iClose( iFileRefI);
  941.             }
  942.             else myErr = MADReadingErr;
  943.         break;
  944.         
  945.         case 'EXPL':
  946.             AlienFile = PPConvertMad2Mod( MadFile, init, &sndSize);
  947.             
  948.             if( AlienFile != 0L)
  949.             {
  950.                 iFileCreate( AlienFileName, 'STrk');
  951.                 iFileRefI = iFileOpen( AlienFileName);
  952.                 if( iFileRefI)
  953.                 {
  954.                     iWrite( sndSize, AlienFile, iFileRefI);
  955.                     iClose( iFileRefI);
  956.                 }
  957.                 DisposePtr( AlienFile);    AlienFile = 0L;
  958.             }
  959.             else myErr = MADReadingErr;
  960.         break;
  961.         
  962.         case 'INFO':
  963.             iFileRefI = iFileOpen( AlienFileName);
  964.             if( iFileRefI)
  965.             {
  966.                 info->fileSize = iGetEOF( iFileRefI);
  967.                 
  968.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  969.                 
  970.                 AlienFile = MADPlugNewPtr( sndSize, init);
  971.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  972.                 else
  973.                 {
  974.                     iRead( sndSize, AlienFile, iFileRefI);
  975.                     
  976.                     myErr = TestMODFile( AlienFile, info->fileSize);
  977.                     
  978.                     if( !myErr) myErr = ExtractMODInfo( info, AlienFile);
  979.                     
  980.                     DisposePtr( AlienFile);    AlienFile = 0L;
  981.                 }
  982.                 iClose( iFileRefI);
  983.             }
  984.             else myErr = MADReadingErr;
  985.         break;
  986.         
  987.         default:
  988.             myErr = MADOrderNotImplemented;
  989.         break;
  990.     }
  991.     
  992.     #ifdef _MAC_H
  993.     #ifndef powerc
  994.         SetA4( oldA4);
  995.     #endif
  996.     #endif
  997.     
  998.     return myErr;
  999. }